package de.szut.gui.options;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Properties;

/**
 * Contains options
 * @author Marc Huisinga
 *
 */
public class Options {
	/**
	 * Default location of the file where the options are saved
	 */
	public static final File OPTIONSFILE = new File("cfg/config.cfg");
	/**
	 * Default default value that gets inserted if the respective key is nonexistent
	 */
	public static final String DEFAULTVALUE = "0";
	
	private String defaultValue;
	private File optionsFile;
	private HashMap<String,String> optionValues;
	
	/**
	 * Gets the file where the options are saved
	 * @return file where the options are saved
	 */
	public File getOptionsFile() {
		return optionsFile;
	}

	/**
	 * Sets the file where the options are saved
	 * @param optionsFile file where the options are saved
	 */
	public void setOptionsFile(File optionsFile) {
		this.optionsFile = optionsFile;
	}
	
	/**
	 * Gets the default value that is inserted when a key isn't found in the options file
	 * @return default value
	 */
	public String getDefaultValue() {
		return defaultValue;
	}

	/**
	 * Sets the default value that is inserted when a key isn't found in the options file
	 * @param defaultValue
	 */
	public void setDefaultValue(String defaultValue) {
		this.defaultValue = defaultValue;
	}

	/**
	 * Gets the last updated values
	 * @return values
	 */
	public HashMap<String,String> getOptionValues() {
		return optionValues;
	}

	/**
	 * Gets a last updated value
	 * @param key key of the value
	 * @return value
	 */
	public String getOptionValue(String key) {
		return optionValues.get(key);
	}

	public Options() {
		optionsFile = OPTIONSFILE;
		defaultValue = DEFAULTVALUE;
		optionValues = new HashMap<String, String>();
	}
	
	/**
	 * Loads the options related to the respective components
	 * @param optionComponents components of which the options are supposed to get loaded
	 */
	public void loadOptions(ArrayList<OptionsComponent> optionComponents) {
		Properties properties = new Properties();
		try {
			optionsFile.createNewFile();
			properties.load(new BufferedInputStream(new FileInputStream(optionsFile)));	
			for (OptionsComponent currentOptionComponent : optionComponents) {
				currentOptionComponent.setOptionComponentState((String) properties.getProperty(currentOptionComponent.getOptionKey(), defaultValue));
				optionValues.put(currentOptionComponent.getOptionKey(), (String) properties.getProperty(currentOptionComponent.getOptionKey(), defaultValue));
			}
		} catch (FileNotFoundException e) {
			System.err.println("Generation of option-file at " + optionsFile.getAbsolutePath() + " failed.");
			for (OptionsComponent currentOptionComponent : optionComponents) {
				currentOptionComponent.setOptionComponentState(defaultValue);
				optionValues.put(currentOptionComponent.getOptionKey(), defaultValue);
			}	
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	
	/**
	 * Loads the options into optionValues from the keys
	 * @param keys keys used for loading
	 */
	public void loadOptionsFromKeys(ArrayList<String> keys) {
		Properties properties = new Properties();
		try {
			optionsFile.createNewFile();
			properties.load(new BufferedInputStream(new FileInputStream(optionsFile)));	
			for (String currentKey : keys) {
				optionValues.put(currentKey, (String) properties.getProperty(currentKey, defaultValue));
			}
		} catch (FileNotFoundException e) {
			System.err.println("Generation of option-file at " + optionsFile.getAbsolutePath() + " failed.");
			for (String currentKey : keys) {
				optionValues.put(currentKey, defaultValue);
			}	
		} catch (IOException e) {
			e.printStackTrace();
		}	
	}
	
	/**
	 * Saves the options into optionsFile
	 * @param optionComponents components of which the values should be saved
	 */
	public void saveOptions(ArrayList<OptionsComponent> optionComponents) {
		Properties properties = new Properties();
		try {
			optionsFile.createNewFile();
			for (OptionsComponent currentOptionComponent : optionComponents) {
				properties.put(currentOptionComponent.getOptionKey(), currentOptionComponent.getOptionComponentState());
				optionValues.put(currentOptionComponent.getOptionKey(), currentOptionComponent.getOptionComponentState());
			}
			properties.store(new BufferedOutputStream(new FileOutputStream(optionsFile)), null);
		} catch (FileNotFoundException e) {
			System.err.println("Generation of option-file at " + optionsFile.getAbsolutePath() + " failed.");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Wrapper for preparing a component.
	 * Adds a key to the component and the component to the list.
	 * @param key key for the component
	 * @param comp component
	 * @param list list for the component
	 */
	public static void prepareComponent(String key, OptionsComponent comp, ArrayList<OptionsComponent> list) {
		comp.setOptionKey(key);
		list.add(comp);
	}
}
